/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package NovoGame.Arkanoid;
import NovoGame.Menu;
import java.io.IOException;
import java.util.Random;
import java.util.Vector;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;
public class ArkanoidJogo extends GameCanvas implements Runnable{
    ArkanoidBarra barra;
    ArkanoidBarra barraDireita;
    ArkanoidBarra barraEsquerda;
    int barraVelocidade = 6;
    ArkanoidBola bola;
    boolean jogar;
    boolean jogarIniciarBola;
    int teclapressionada = 0;
    Image fundoInicio;
    Image fundo;
    int fundoL;
    int fundoA;
    int largura;
    int altura;
    int paredeMaxX = 0;
    int paredeMaxY = 0;
    int paredeMinX = 0;
    int paredeMinY = 0;
    int pontos = 0;
    int tempo = 0;
    int tempo_periodo = 0;
    int tijolosAcertados = 0;
    int vidas = 3;
    Menu meuJogo;
    String debug;
    public static final int TIJOLO_ALTURA = 10;
    public static final int TIJOLO_LARGURA = 20;
    Vector tijolos;
    public ArkanoidJogo(boolean teclaEventos, Menu meuJogo){
        super(teclaEventos);
        this.meuJogo = meuJogo;
        this.jogar = true;
        this.jogarIniciarBola = false;
        try{
            fundo = Image.createImage("/NovoGame/img/bg.png");
            fundoL = fundo.getWidth();
            fundoA = fundo.getHeight();
            fundoInicio = Image.createImage("/NovoGame/img/comecar.png");
        }catch(IOException e){
            e.printStackTrace();
        }
    }
    public void inicio(){
        Image imagemBarra = null;
        try {
            imagemBarra = Image.createImage("/NovoGame/img/barra.png");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        barra = new ArkanoidBarra(imagemBarra, 14, 30);
        barra.imgPosicao = 1;
        barra.setX((getWidth()-barra.getLargura())/2);
        barra.setY(getHeight()-barra.getAltura());
        barra.setMaxLimite(getWidth()-10);
        barra.setMinLimite(10);
        barra.setVelocidadeX(4);
        
        barraDireita = new ArkanoidBarra(imagemBarra, barra.getAltura(), 10);
        barraDireita.imgPosicao = 2;
        barraDireita.setX(barra.getX()+barra.getLargura());
        barraDireita.setY(barra.getY());
        barraDireita.setMaxLimite(getWidth());
        barraDireita.setMinLimite(barra.getLargura()+10);
        barraDireita.setVelocidadeX(barra.getVelocidadeX());
        
        barraEsquerda = new ArkanoidBarra(imagemBarra, barra.getAltura(), 10);
        barraEsquerda.imgPosicao = 0;
        barraEsquerda.setX(barra.getX()-10);
        barraEsquerda.setY(barra.getY());
        barraEsquerda.setMaxLimite(getWidth()-barra.getLargura()-barraDireita.getLargura());
        barraEsquerda.setMinLimite(0);
        barraEsquerda.setVelocidadeX(barra.getVelocidadeX());
        
        bola = new ArkanoidBola(4);
        bola.setX(getWidth()/2);
        bola.setY(barra.getY()-bola.getAltura());
        bola.setVelocidadeX(3);
        bola.setVelocidadeY(3);
        bola.setVelocidadeMaxX(4);
        bola.setVelocidadeMaxY(4);
        
        //Area de colisão
        paredeMinX = 0;
        paredeMaxX = getWidth();    
        paredeMinY = 0;
        // um pouco maior para poder sair da tela
        paredeMaxY = getHeight()+4*bola.getAltura();
        
        //Criando tijolos
        ArkanoidTijolo tijolo;
        tijolos = new Vector();
        Random aleatorio = new Random();
        for (int i=0; (i*(TIJOLO_LARGURA+2))<getWidth(); i++){
            aleatorio.setSeed(System.currentTimeMillis()+i);
            int n = Math.abs(aleatorio.nextInt()%5)+1;
            tijolo = new ArkanoidTijolo(0x00A52C25);
            tijolo.setDificuldade(n);
            tijolo.setLargura(TIJOLO_LARGURA);
            tijolo.setAltura(TIJOLO_ALTURA);
            tijolo.setX(i*(tijolo.getLargura()+2));
            tijolo.setY(25);
            tijolos.addElement(tijolo);
        }
    }
    public void start(){
        jogar = true;
        Thread t = new Thread(this);
        t.start();
    }
    public void stop(){
        jogar = false;
        vidas=0;
    }
    public void run(){
        inicio();
        while(jogar){
            atualizaStatusJogo();
            verificaInteracaoUsuario();
            atualizaTelaJogo(this.getGraphics());
            this.flushGraphics();
            try {
                Thread.sleep(10);
            } catch (InterruptedException ex) {
                ex.printStackTrace();
            }
        }
        meuJogo.fimJogo(vidas, pontos, tempo);
    }
    // Verifica interação do usuário
    protected void keyPressed(int keyCode) {
        int gameAction = getGameAction(keyCode);
        teclapressionada = 0;
        switch(gameAction){
            case LEFT:
                teclapressionada = 3;
            break;
            case RIGHT:
                teclapressionada = 2;
            break;
            case FIRE:
            case FIRE_PRESSED:
                setAtirar();
            break;
        }
        switch(keyCode){
            case KEY_NUM4:
                teclapressionada = 3;
            break;
            case KEY_NUM2:
            case KEY_NUM5:
                setAtirar();
            break;
            case KEY_NUM6:
                teclapressionada = 2;
            break;
        }
    }
    protected void keyReleased(int keyCode) {
        int gameAction = getGameAction(keyCode);
        switch(gameAction){
            case LEFT:
                teclapressionada = 0;
            break;
            case RIGHT:
                teclapressionada = 0;
                break;
            case FIRE:
                teclapressionada = 0;
                break;
        }
        switch(keyCode){
            case KEY_NUM4:
                teclapressionada = 0;
            break;
            case KEY_NUM5:
                teclapressionada = 0;
            break;
            case KEY_NUM6:
                teclapressionada = 0;
            break;
        }
    }
    protected void pointerPressed(int x, int y) {
        debug = " Ax"+x+"Y"+y;
    }
    protected void pointerReleased(int x, int y){
        if(!jogarIniciarBola && ((getWidth()/2)-(fundoInicio.getWidth()/2)) < x && ((getWidth()/2)+(fundoInicio.getWidth()/2)) > x && ((getHeight()/2)-(fundoInicio.getHeight()/2)) < y && ((getHeight()/2)+(fundoInicio.getHeight()/2)) > y ){
            setAtirar();
        }
    }
    protected void pointerDragged(int x, int y) {
        barra.setX(x);
        barraEsquerda.setX(x-barraEsquerda.getLargura());
        barraDireita.setX(x+barra.getLargura());
    }
    //Evento para começar ou disparar
    private void setAtirar(){
        this.jogarIniciarBola = true;
    }
    //Evento para Direita
    private void setDireita(){
        barra.setVelocidadeX(barraVelocidade);
        barraDireita.setVelocidadeX(barraVelocidade);
        barraEsquerda.setVelocidadeX(barraVelocidade);
    }
    //Evento para Esquerda
    private void setEsquerda(){
        barra.setVelocidadeX(-barraVelocidade);
        barraDireita.setVelocidadeX(-barraVelocidade);
        barraEsquerda.setVelocidadeX(-barraVelocidade);
    }
    //Caso nenhum evento esteja acontecendo
    private void setParado(){
        barra.setVelocidadeX(0);
        barraDireita.setVelocidadeX(0);
        barraEsquerda.setVelocidadeX(0);
    }
    //Atualiza os elementos do jogo.. Posição, Colisão...
    private void atualizaStatusJogo(){
        barra.atualizar();
        barraDireita.atualizar();
        barraEsquerda.atualizar();
        if(jogarIniciarBola){
            bola.atualizar();
        }else{
            bola.setX((barra.getLargura()/2)+barra.getX()-(bola.getLargura()/2));
        }
        
        verificaColisaoBolaParede();
        verificaColisaoBarraBola();
        verificaColisaoBarraDireitaBola();
        verificaColisaoBarraEsquerdaBola();
        verificaColisaoBolaTijolos();
        verificaBolaFora();
        //ganhou os tijolos acabaram
        jogar = false;
        int ativos = 0;
        for(int i=0; i<tijolos.size();i++){
            ArkanoidTijolo tijolo = (ArkanoidTijolo)(tijolos.elementAt(i));
            if(tijolo.isAtivo()){
                ativos++;
                jogar = true;
                break;
            }
        }
        debug = " - "+tijolos.size()+" "+ativos+"; ";
        if(vidas <=0){
            jogar = false;
        }
    }
    //verificar colisão da bola nas paredes
    private void verificaColisaoBolaParede(){
        //Limites horizontais
        if(bola.getX() + bola.getLargura() > paredeMaxX){
            bola.setX(paredeMaxX - bola.getLargura());
            bola.setVelocidadeX(-bola.getVelocidadeX());
        }
        if(bola.getX() < paredeMinX){
            bola.setX(paredeMinX);
            bola.setVelocidadeX(-bola.getVelocidadeX());
        }
        //Limites verticais
        if(bola.getY() + bola.getAltura() > paredeMaxY){
            bola.setY(paredeMaxY-altura);
            bola.setVelocidadeY(-bola.getVelocidadeY());
        }
        if(bola.getY() < paredeMinY){
            bola.setY(paredeMinY);
            bola.setVelocidadeY(-bola.getVelocidadeY());
        }
    }
    //verificar colisão da bola na barra
    private void verificaColisaoBarraBola(){
        byte colisao = barra.colisao(bola);
        if(barra.colisaoHorizontal(colisao)){
            /*lado = (barra.getPosicaoColisaoX()-(barra.getLargura()/2));
            bola.setX(bola.getVelhaX());
            if(lado < 0){
                lado = -lado;
                inverter = true;
            }
            porcento = ((100*lado)/(barra.getLargura()/2));
            debug = "|"+porcento;
            if(porcento <= 15){
                bola.setVelocidadeX(0);
            }else if(porcento >= 90){
                bola.setVelocidadeX(bola.getVelocidadeMaxX());
            }else{
                bola.setVelocidadeX((porcento * bola.getVelocidadeMaxX())/100);
                if(bola.getVelocidadeX() == 0){
                    bola.setVelocidadeX(1);
                }
            }
            if(inverter){
                bola.setVelocidadeX(-bola.getVelocidadeX());
            }
            debug += "|"+bola.getVelocidadeX();
            debug += "|"+bola.getVelocidadeMaxX();*/
            bola.setX(bola.getVelhaX());
            bola.setY(bola.getVelhaY());
            bola.setVelocidadeX(bola.getVelocidadeX());
        }
        if(barra.colisaoVertical(colisao)){
            bola.setX(bola.getVelhaX());
            bola.setY(bola.getVelhaY());
            bola.setVelocidadeY(-bola.getVelocidadeY());
        }
    }
    private void verificaColisaoBarraDireitaBola(){
        byte colisao = barraDireita.colisao(bola);
        if(barraDireita.colisaoHorizontal(colisao)){
            bola.setX(bola.getVelhaX()-5);
            bola.setY(bola.getVelhaY()-5);
            bola.setVelocidadeX(-bola.getVelocidadeX());
        }
        if(barraDireita.colisaoVertical(colisao)){
            bola.setX(bola.getVelhaX());
            bola.setY(bola.getVelhaY());
            bola.setVelocidadeY(-bola.getVelocidadeY());
        }
        colisao = barraDireita.colisao(bola);
        if(barraDireita.colisaoVertical(colisao)){
            bola.setX(barraDireita.getX()-bola.getLargura());
            //bola.setY(barraDireita.getY()-bola.getAltura());
        }
    }
    private void verificaColisaoBarraEsquerdaBola(){
        byte colisao = barraEsquerda.colisao(bola);
        if(barraEsquerda.colisaoHorizontal(colisao)){
            bola.setX(bola.getVelhaX()-5);
            bola.setY(bola.getVelhaY()-5);
            if(bola.getVelocidadeX() > 0){
                bola.setVelocidadeX(-bola.getVelocidadeX());
            }
        }
        if(barraEsquerda.colisaoVertical(colisao)){
            bola.setX(bola.getVelhaX());
            bola.setY(bola.getVelhaY());
            bola.setVelocidadeY(-bola.getVelocidadeY());
        }
        colisao = barraEsquerda.colisao(bola);
        if(barraEsquerda.colisaoVertical(colisao)){
            bola.setX(barraEsquerda.getX()+bola.getLargura());
            bola.setY(barraEsquerda.getY()-bola.getAltura());
        }
    }
    //verificar colisão da bola nos tijolos
    private void verificaColisaoBolaTijolos(){
        byte colisao;
        for(int i =0; i < tijolos.size(); i++){
            ArkanoidTijolo tijolo = (ArkanoidTijolo)(tijolos.elementAt(i));
            if(tijolo.isAtivo()){
                colisao = bola.colisao(tijolo);
                if(bola.colisaoHorizontal(colisao)){
                    bola.setX(bola.getVelhaX());
                    bola.setVelocidadeX(-bola.getVelocidadeX());
                }
                if(bola.colisaoVertical(colisao)){
                    bola.setY(bola.getVelhaY());
                    bola.setVelocidadeY(-bola.getVelocidadeY());
                }
                //Se a colisão aconteceu fazer tijolos desaparecer
                if(colisao != ArkanoidEntidade.COLISAO_NENHUMA){
                    tijolo.setDificuldade(tijolo.getDificuldade()-1);
                    pontos += 10;
                    tijolosAcertados ++;
                    meuJogo.getDisplay().vibrate(500);
                }
            }
        }
    }
    // verifica bola longe da tela
    private void verificaBolaFora(){
        if(bola.getY() > getHeight()){
            vidas --;
            if(vidas == 0){
                //Fim do jogo
                jogar = false;
            }else{
                jogarIniciarBola = false;
                bola.setX(barra.getX());
                bola.setY(barra.getY()-(bola.getAltura()));
            }
        }
    }
    // Verifica interação do usuário
    private void verificaInteracaoUsuario(){
        if(teclapressionada == 0){
            int estado = getKeyStates();
            if((estado & GameCanvas.FIRE_PRESSED) > 0){
                setAtirar();
            }
        }
        if(teclapressionada == 2){
            setDireita();
        }else if(teclapressionada == 3){
            setEsquerda();
        }else{
            setParado();
        }
    }
    private void atualizaTelaJogo(Graphics g){
        if(jogarIniciarBola){
            tempo_periodo ++;
            if(tempo_periodo >= 10){
                tempo++;
                tempo_periodo = 0;
            }
        }
        largura = getWidth();
        altura = getHeight();
        //g.setColor(255,255,255);
        //g.fillRect(0, 0, largura, altura);
        imagemDeFundo(g);
        //debug = "!"+barraEsquerda.getX()+"!"+barra.getX()+"!"+barraDireita.getX();
        g.setColor(0,0,0);
        g.drawString("Ponto: "+pontos+" Vidas: "+vidas+" tempo: "+tempo+debug, 0, 0, Graphics.TOP|Graphics.LEFT);
        
        barra.pintar(g, 0x00000000);
        barraDireita.pintar(g, 0x000000ff);
        barraEsquerda.pintar(g, 0x00ff0000);
        bola.pintar(g);
        for (int i = 0; i < tijolos.size(); i++) {
            ArkanoidTijolo tijolo = (ArkanoidTijolo) (tijolos.elementAt(i));
            tijolo.pintar(g);
        }
        if(!jogarIniciarBola){
            g.drawImage(fundoInicio, (largura/2)-(fundoInicio.getWidth()/2), (altura/2)-(fundoInicio.getHeight()/2), Graphics.TOP | Graphics.LEFT);
        }
    }
    private void imagemDeFundo(Graphics g){
        for(int i=0; (i*fundoL)<= getWidth(); i++){
            for(int y=0; (y*fundoA)<= getHeight(); y++){
                g.drawImage(fundo, (fundoL*i), (fundoA*y), Graphics.TOP|Graphics.LEFT);
            }
        }
    }
}
